package com.example.spring.bean.load02scan;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;

/**
 * ComponentScan注解
 * <p> 默认扫描本目录下和所有子目录
 * <p> value: 指定要扫描的包。
 * <p> excludeFilters: 指定扫描的时候按照什么规则排除组件。
 * <p> includeFilters: 指定扫描的时候只需要包含哪些组件。
 * <p> useDefaultFilters: 是否对使用 @Service、@Controller、@Component、@Repository 类进行扫描。
 *
 * <p>扫描过滤器的扫描规则如下------------------------------
 * <p>
 *     <ul>
 *         <li>FilterType.ANNOTATION：按照注解类型，如 Controller、Service 等；</li>
 *         <li>FilterType.ASSIGNABLE_TYPE：按照给定的类型；比如指定Bean(class类) ；</li>
 *         <li>FilterType.ASPECTJ：使用ASPECTJ表达式 ；</li>
 *         <li>FilterType.REGEX：使用正则；</li>
 *         <li>FilterType.CUSTOM：使用自定义规则，自已写类，实现TypeFilter接口。</li>
 *     </ul>
 * <p>
 * <p>
 */
@Configuration
@ComponentScan(value = {"com.example.spring.bean.load02scan"},
        //指定对 Controller 生效
        includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class})},
        //上面指定只对Controller生效，这里需要把这个配置设置成false，否则 Service、Component、Repository 等还会被扫描进去
        useDefaultFilters = false)
public class ScanConfig {
    /**
     * ClassPathBeanDefinitionScanner类中
     *
     * 构造方法
     * public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
     * 	    Environment environment, @Nullable ResourceLoader resourceLoader) {
     *
     * 	    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
     * 	    this.registry = registry;
     *
     * 	    if (useDefaultFilters) {
     * 		    registerDefaultFilters();
     *        }
     * 	    setEnvironment(environment);
     * 	    setResourceLoader(resourceLoader);
     * }
     *
     * //registerDefaultFilters方法
     * protected void registerDefaultFilters() {
     * 		this.includeFilters.add(new AnnotationTypeFilter(Component.class));
     * 	    //...
     * }
     *
     */
}
